home *** CD-ROM | disk | FTP | other *** search
- /* -*-C-*- dvieps.c */
- /*-->dvieps*/
- /**********************************************************************/
- /******************************* dvieps *******************************/
- /**********************************************************************/
-
- /***********************************************************************
- DVIEPS was developed from one of the dot-matrix printer drivers by
- Marcus Moehrmann (EMAIL: marcus%fkihh@unido.uucp). The following
- remarks are his.
-
- This is an implementation for Epson and compatible printers. Printers
- with 9 needles are supported; those with 24 are not. I hope that I have
- only used the ESC/P-Standard. The only documentation I have had was a
- description for the NEC Pinwriter P6/P7, but our printer is a Logitec,
- which I used for testing.
-
- There is a difference in paper feeding, because the P6/P7-handbook says
- that
-
- <ESC> J (n)
-
- performs n/180 inch paper feeding, but our printer performs n/216 inch
- paper feeding, which I think is the standard, so I have used this in the
- driver.
-
- For horizontal resolution I have used the Esc-sequences
-
- <ESC> * (m) (n1) (n2) [m = 0, 1, 2, 3]
-
- instead of
-
- <ESC> (x) (n1) (n2) [x = 'K', 'L', 'Y', 'Z']
-
- If this will not work on your printer, change the definitions of
- 'EPSON_BIT_IMAGE' and 'EPSON_MICRO_STEP' and the variable 'resolution'
- in procedure 'outline'.
-
- Be careful with the reset command
-
- <ESC> @
-
- I have done this before any printing, and then after about 1.5 pages the
- printer stopped. The same works quite well on a second printer.
-
- Specialities: There is a switch '-t' for twice-a-line printing, that is,
- print one line in 1/120 inch horizontal spacing, return print head
- without paper feeding, perform a 1/240 inch step and then print the
- second line with 1/120 inch spacing.
-
- ***********************************************************************/
-
- #include "dvihead.h"
-
- /**********************************************************************/
- /************************ Device Definitions ************************/
- /**********************************************************************/
-
- /* All output-device-specific definitions go here. This section must
- be changed when modifying a dvi driver for use on a new device */
-
- #undef EPSON
- #define EPSON 1 /* conditional compilation flag */
-
- #define VERSION_NO "2.10 [experimental]" /* DVI driver version number */
-
- #undef HIRES
- #define HIRES 1 /* 0 for 72-dpi version */
-
- #if HIRES
- #define DEVICE_ID "Epson 9-pin family 240/216-dpi matrix printer"
- /* this string is printed at runtime */
- #define OUTFILE_EXT "eps"
-
- #define XDPI 240 /* horizontal dots/inch */
- #define YDPI 216 /* vertical dots/inch */
-
- #else /* NOT HIRES */
- #define DEVICE_ID "Epson 9-pin family 60/72-dpi matrix printer"
- /* this string is printed at runtime */
-
- #define OUTFILE_EXT "e72"
-
- #define XDPI 60 /* horizontal dots/inch */
- #define YDPI 72 /* vertical dots/inch */
- #endif /* HIRES */
-
- #define BYTE_SIZE 8 /* output file byte size */
-
- #undef STDRES
- #if HIRES
- #define STDRES 1 /* 0 for low-resolution devices */
- #else /* NOT HIRES */
- #define STDRES 0 /* 0 for low-resolution devices */
- #endif /* HIRES */
-
- #if OS_PCDOS
- #define XPSIZE 6 /* horizontal paper size in inches */
- #else /* NOT OS_PCDOS */
- #define XPSIZE 8 /* horizontal paper size in inches */
- #endif /* OS_PCDOS */
-
- #define XSIZE (((XDPI*XPSIZE+2*HOST_WORD_SIZE-1)/\
- (2*HOST_WORD_SIZE))*(2*HOST_WORD_SIZE))
- /* number of horizontal dots; */
- /* MUST BE multiple of */
- /* 2*HOST_WORD_SIZE */
- #define XWORDS ((XSIZE + HOST_WORD_SIZE - 1)/HOST_WORD_SIZE)
- /* number of words in rows */
- /* of bitmap array */
-
- #if OS_PCDOS
- #define YPSIZE 8 /* vertical paper size in inches */
- #else /* NOT OS_PCDOS */
- #define YPSIZE 11 /* vertical paper size in inches */
- #endif /* OS_PCDOS */
-
- #define YSIZE (YDPI*YPSIZE) /* number of vertical dots */
-
- #if HIRES
- INT16 paperfeeding; /* outstanding 1/216 inch */
- /* form-feedings */
-
- BOOLEAN twice_a_line = FALSE; /* this is runtime option '-t' */
- /* print in 1/120-inch-mode, */
- /* 2nd line shifted 1/240 inch */
-
- /* need single-arg outline() */
- BOOLEAN micro_step; /* used in outline() */
- #define OUTLINE(v,flag) {micro_step = flag; outline(v);}
- #endif /* HIRES */
-
- /* The printer bit map. */
-
- #define XBIT XWORDS
- #define YBIT YSIZE
-
- #if (IBM_PC_LATTICE | IBM_PC_MICROSOFT | IBM_PC_WIZARD)
- #undef SEGMEM
- #define SEGMEM 1 /* ( ((long)XBIT * (long)YBIT) > 65536L ) */
- #endif /* (IBM_PC_LATTICE | IBM_PC_MICROSOFT | IBM_PC_WIZARD) */
-
- #define EPSON_ADV_PAPER "\033J%c" /* advance paper n/216 inch */
- #define EPSON_BIT_IMAGE "\033*%c%c%c"
- #define EPSON_MICRO_STEP OUTF2("\033*\003\001%c%c",'\000','\000')
-
- #include "bitmap.h"
-
- #include "main.h"
- #include "abortrun.h"
- #include "actfact.h"
- #include "alldone.h"
- #include "chargf.h"
- #include "charpk.h"
- #include "charpxl.h"
- #include "clrbmap.h"
- #include "clrrow.h"
- #include "dbgopen.h"
-
- /*-->devinit*/
- /**********************************************************************/
- /****************************** devinit *******************************/
- /**********************************************************************/
-
- void
- devinit(argc, argv) /* initialize device */
- int argc;
- char *argv[];
- {
- (void)getbmap();
- if (runlengthcode && !quiet)
- {
- (void)fprintf(stderr, "[Run-length encoding of output file]");
- NEWLINE(stderr);
- }
-
- #if HIRES
- if (twice_a_line && !quiet)
- {
- (void)fprintf(stderr, "[Twice-a-line-printing for high resolution]");
- NEWLINE(stderr);
- }
- #endif /* HIRES */
-
- }
-
- /*-->devterm*/
- /**********************************************************************/
- /****************************** devterm *******************************/
- /**********************************************************************/
-
- void
- devterm() /* terminate device */
- {
- }
-
- #include "dispchar.h"
- #include "dvifile.h"
- #include "dviinit.h"
- #include "dviterm.h"
- #include "f20open.h"
- #include "fatal.h"
- #include "fillrect.h"
- #include "findpost.h"
- #include "fixpos.h"
- #include "fontfile.h"
- #include "fontsub.h"
- #include "getbmap.h"
- #include "getbytes.h"
- #include "getfntdf.h"
- #include "getpgtab.h"
- #include "inch.h"
- #include "initglob.h"
- #include "loadchar.h"
-
- /*-->makechar*/
- /**********************************************************************/
- /****************************** makechar ******************************/
- /**********************************************************************/
-
- char
- makechar(p, mask)
- register UNSIGN32 *p[];
- register UNSIGN32 mask;
- {
- register char c;
-
- #if SEGMEM
- #define Q(n) p[n] /* use precomputed pointers */
- #else /* NOT SEGMEM */
- #define Q(n) (p[0] - (n)*XBIT) /* compute pointers on the fly */
- #endif /* SEGMEM */
-
- c = '\000'; /* MSB controls top needle */
-
- #if HIRES
- if (*Q(0) & mask)
- c |= '\200';
- if (*Q(3) & mask)
- c |= '\100';
- if (*Q(6) & mask)
- c |= '\040';
- if (*Q(9) & mask)
- c |= '\020';
- if (*Q(12) & mask)
- c |= '\010';
- if (*Q(15) & mask)
- c |= '\004';
- if (*Q(18) & mask)
- c |= '\002';
- if (*Q(21) & mask)
- c |= '\001';
- #else /* NOT HIRES */
- if (*Q(0) & mask)
- c |= '\200';
- if (*Q(1) & mask)
- c |= '\100';
- if (*Q(2) & mask)
- c |= '\040';
- if (*Q(3) & mask)
- c |= '\020';
- if (*Q(4) & mask)
- c |= '\010';
- if (*Q(5) & mask)
- c |= '\004';
- if (*Q(6) & mask)
- c |= '\002';
- if (*Q(7) & mask)
- c |= '\001';
- #endif /* HIRES */
-
- return (c);
- }
-
- #include "movedown.h"
- #include "moveover.h"
- #include "moveto.h"
- #include "nosignex.h"
- #include "openfont.h"
- #include "option.h"
-
- #if HIRES
- /*-->outpaperfeed*/
- /**********************************************************************/
- /*************************** outpaperfeed *****************************/
- /**********************************************************************/
-
- #ifdef __STDC__
- void outpaperfeed(INT16 count)
- #else
- void
- outpaperfeed(count) /* accumulate 1/216 inch paperfeedings */
- INT16 count; /* and write them out if count == 0 */
- #endif
- {
-
- register INT16 k;
-
- if (count)
- paperfeeding += count;
- else
- {
- for (k = paperfeeding / 255; k; --k)
- OUTF(EPSON_ADV_PAPER, 255);
- if ((k = paperfeeding % 255) > 0)
- OUTF(EPSON_ADV_PAPER, k);
- paperfeeding = 0;
- }
- }
- #endif /* HIRES */
-
- /*-->outline*/
- /**********************************************************************/
- /****************************** outline *******************************/
- /**********************************************************************/
-
- void
- outline(pline)
- char *pline;
- {
- register char* a;
- register char* b;
- register char* c;
- register INT16 left;
- INT16 len;
- INT16 linelength;
- char resolution;
- BYTE spacing;
- BYTE space_width;
-
- #if HIRES
- if (twice_a_line) /* step 1/240 inch forward */
- {
- resolution = '\001'; /* 1/120 */
- space_width = 12; /* 12/120 */
- linelength = XSIZE / 2;
- }
- else
- {
- resolution = '\003'; /* 1/240 */
- space_width = 24; /* 24/240 */
- linelength = XSIZE;
- }
- #else /* NOT HIRES */
- resolution = '\000'; /* 1/60 */
- space_width = 6; /* 6/60 */
- linelength = XSIZE;
- #endif /* HIRES */
-
- for ((left = linelength, c = pline + linelength - 1);
- (*c == '\000') && (left > 0);
- (--left, --c)) /* trim white space */
- ;
-
- if (left == 0)
- return; /* NEWLINE() is not needed for any paperfeeding */
-
- #if HIRES
- (void)outpaperfeed(0); /* print accumulated paperfeedings */
- #endif /* HIRES */
-
- /*******************************************************************
- We search for runs as follows. "b" marks the beginning of unwritten
- data, and "a" anchors the beginning of a run which continues to just
- before "c". The run length is "c"-"a". Only runs longer than
- "space_width" are taken, because we print spaces in text mode. This
- implies that the run only consists of '\000' characters.
-
- If a long enough run is found, then the string "b" .. "a"-1 is
- output since its length is now known, followed by the run encoding
- for the character at "a". Then "a" and "b" are advanced to "c", and
- the scan continues.
-
- If the run beginning at "a" is too short, then "a" is simply
- advanced.
-
- Since the character strings take on all values on 0 .. 255, we
- cannot store a termination marker, but must instead keep a counter,
- "left", which is decremented to 0 when the end of the string is
- reached.
-
- ?????????????0000000000000000????????????????????
- ^ ^ ^
- | | |
- b a c
-
- <-----run------>
-
-
- We cannot use fprintf %s because 0 bytes terminate string, so we are
- using putc for writing the line.
- *******************************************************************/
-
- if (runlengthcode && (left >= space_width))
- {
- for (a = b = pline; (left > 0); --left)
- {
- for (c = a; (*a == *++c) && (*a == '\000') && left; --left)
- ; /* advance over run */
- len = (INT16) (c - a); /* "c" points past run */
-
- if (len >= space_width) /* output long run */
- {
- if (a > b) /* output previous string */
- {
- #if HIRES
- if (micro_step)
- {
- EPSON_MICRO_STEP;
- micro_step = FALSE;
- }
- #endif /* HIRES */
- OUTF3(EPSON_BIT_IMAGE, resolution, ((int) (a - b)) % 256,
- ((int) (a - b)) / 256);
- for (; b < a; b++)
- OUTC(*b);
- }
-
- c -= len % space_width; /* shorten run */
- left += len % space_width;
-
- for (spacing = (BYTE)(len / space_width); spacing; --spacing)
- OUTC(' '); /* output run */
-
- a = b = c;
- }
- else /* ignore short run */
- {
- ++a;
- left += len - 1;
- }
- } /* end for() loop */
-
- if (a > b) /* output remaining string */
- {
- #if HIRES
- if (micro_step)
- {
- EPSON_MICRO_STEP;
- micro_step = FALSE;
- }
- #endif /* HIRES */
- OUTF3(EPSON_BIT_IMAGE,resolution,((int) (a - b)) % 256,
- ((int) (a - b)) / 256);
- for (; b < a; b++)
- OUTC(*b);
- }
- }
- else /* no runlength coding */
- if (left > 0)
- {
- #if HIRES
- if (micro_step)
- {
- EPSON_MICRO_STEP;
- micro_step = FALSE;
- }
- #endif /* HIRES */
- OUTF3(EPSON_BIT_IMAGE,resolution,left % 256,left / 256);
- for (c = pline; left; --left, c++)
- OUTC(*c);
- }
- NEWLINE(plotfp);
- }
-
- #include "outrow.h"
-
- /*-->prtbmap*/
- /**********************************************************************/
- /****************************** prtbmap *******************************/
- /**********************************************************************/
-
- void
- prtbmap()
- {
- register BYTE *c; /* pointer into v8[][] and v8t[][][] */
- UNSIGN32 *p; /* pointer into bitmap[][] */
-
- #if SEGMEM
- #else /* NOT SEGMEM */
- UNSIGN32 *ptmp; /* pointer into bitmap[][] */
- #endif /* SEGMEM */
-
- register UNSIGN32 mask; /* mask for single bit selection */
- register INT16 k;
- INT16 i;
- INT16 j;
- INT16 ybottom;
- INT16 ytop;
-
- #if HIRES
- BYTE v8[3][XSIZE]; /* vertical 8-bit raster encodings */
- BYTE v8t[3][2][XSIZE / 2]; /* vertical 8-bit raster encodings */
- /* (twice-a-line) */
- INT16 second = 0; /* address second byte if not zero */
-
- #undef Q
- #if SEGMEM
- UNSIGN32 *q[24]; /* pointers to 24 raster lines */
- #define Q(n) q[n] /* use precomputed pointers */
- #else /* NOT SEGMEM */
- #define Q(n) (p - (n)*XBIT) /* compute pointers on the fly */
- #endif /* SEGMEM */
-
- (void)clearerr(plotfp);
-
- ytop = YBIT - 1;
-
- k = -1; /* find bottom non-zero raster */
- for (j = 0; (j < ytop) && (k < 0); ++j) /* loop over raster lines */
- {
-
- #if IBM_PC_MICROSOFT
- for (k = XBIT - 1; ((k >= 0) && (*BITMAP(j, k) == 0)); --k)
- ; /* trim white space */
-
- #else /* NOT IBM_PC_MICROSOFT */
- p = BITMAP(j, XBIT - 1);
- for (k = XBIT - 1; ((k >= 0) && (*p == 0)); --k)
- --p; /* trim white space */
- #endif /* IBM_PC_MICROSOFT */
-
- }
- ybottom = (j / 24) * 24 + 23;
-
- paperfeeding = 0; /* for outpaperfeed() */
- OUTF("\0333%c", 0); /* no paperfeeding */
-
- for (j = ytop; (j >= ybottom); j -= 24) /* loop over raster lines */
- { /* in groups of 24 */
-
- #if SEGMEM
- #else /* NOT SEGMEM */
- p = BITMAP(j, 0); /* the j-th raster line */
- #endif /* SEGMEM */
-
- if (twice_a_line)
- c = &v8t[0][0][0]; /* vertical 8-bit encodings */
- else
- c = &v8[0][0]; /* vertical 8-bit encodings */
-
- for (i = 0; i < XBIT; (++p, ++i)) /* loop over raster words */
- {
- /* PCC-20 compiled (1 << (HOST_WORD_SIZE-1)) to 0, so do it the
- hard way, arghh... */
- mask = 1;
- mask <<= (HOST_WORD_SIZE - 1); /* to select leftmost bit */
-
- #if SEGMEM
- for (k = 0; k < 24; ++k) /* compute pointers to 24 rasters */
- q[k] = BITMAP(j - k, i);
- #endif /* SEGMEM */
-
- for (k = 0; k < HOST_WORD_SIZE; (++k)) /* loop over word bits */
- {
- /* examine bits in 24 adjacent rows and build two 8-bit */
- /* character values, the first with rows n,n+3,...,n+21, */
- /* the second with rows n+1,n+4,...,n+22, the third with */
- /* rows n+2,n+5,...,n+23. The 2nd and 3rd characters are */
- /* then printed with 1 dot vertical spacing. */
-
- /* if twice_a_line is TRUE, the bytes will be written */
- /* alternating in v8t[x][0][y] and v8t[x][1][y] */
-
- if (twice_a_line)
- second = (k % 2) * XSIZE / 2;
-
- #if SEGMEM
- *(c + second) = (BYTE) makechar(&q[0], mask);
- *(c + XSIZE + second) = (BYTE) makechar(&q[1], mask);
- *(c + 2 * XSIZE + second) = (BYTE) makechar(&q[2], mask);
- #else /* NOT SEGMEM */
- *(c + second) = (BYTE) makechar(&p, mask);
- ptmp = p - XBIT;
- *(c + XSIZE + second) = (BYTE) makechar(&ptmp, mask);
- ptmp = p - 2 * XBIT;
- *(c + 2 * XSIZE + second) = (BYTE) makechar(&ptmp, mask);
- #endif /* SEGMEM */
-
- if (twice_a_line)
- {
- if (second)
- c++; /* increment after second byte */
- }
- else
- c++;
-
- mask >>= 1; /* move masking bit right 1 position */
- } /* end loop over k */
- } /* end loop over i */
-
- if (twice_a_line)
- {
- OUTLINE((char *) &v8t[0][0][0], FALSE);
- OUTLINE((char *) &v8t[0][1][0], TRUE);
- (void)outpaperfeed(1);
- OUTLINE((char *) &v8t[1][0][0], FALSE);
- OUTLINE((char *) &v8t[1][1][0], TRUE);
- (void)outpaperfeed(1);
- OUTLINE((char *) &v8t[2][0][0], FALSE);
- OUTLINE((char *) &v8t[2][1][0], TRUE);
- (void)outpaperfeed(22);
- }
- else
- {
- OUTLINE((char *) &v8[0][0], FALSE);
- (void)outpaperfeed(1);
- OUTLINE((char *) &v8[1][0], FALSE);
- (void)outpaperfeed(1);
- OUTLINE((char *) &v8[2][0], FALSE);
- (void)outpaperfeed(22);
- }
-
- } /* end loop over j */
-
- OUTS("\0332"); /* ESC 2 = normal paperfeeding */
- OUTC('\f'); /* eject page with FF */
-
- (void)fflush(plotfp);
- if (DISKFULL(plotfp))
- (void)fatal("prtbmap(): Output error -- disk storage probably full");
- }
-
- #else /* NOT HIRES */
- BYTE v8[XSIZE + 2]; /* vertical 8-bit raster encodings */
-
- #undef Q
- #if SEGMEM
- UNSIGN32 *q[8]; /* pointers to 8 raster lines */
- #define Q(n) q[n] /* use precomputed pointers */
- #else /* NOT SEGMEM */
- #define Q(n) (p - (n)*XBIT) /* compute pointers on the fly */
- #endif /* SEGMEM */
-
- ytop = YBIT - 1;
-
- k = -1; /* find bottom non-zero raster */
- for (j = 0; (j < ytop) && (k < 0); ++j) /* loop over raster lines */
- {
-
- #if IBM_PC_MICROSOFT
- for (k = XBIT - 1; ((k >= 0) && (*BITMAP(j, k) == 0)); --k)
- ; /* trim white space */
- #else /* NOT IBM_PC_MICROSOFT */
- p = BITMAP(j, XBIT - 1);
- for (k = XBIT - 1; ((k >= 0) && (*p == 0)); --k)
- --p; /* trim white space */
- #endif /* IBM_PC_MICROSOFT */
-
- } /* end loop over j */
- ybottom = (j / 8) * 8 + 7;
-
- OUTF("\0333%c", 24); /* 24/216 inch paperfeeding */
-
- for (j = ytop; (j >= ybottom); j -= 8) /* loop over raster lines */
- { /* in groups of 8 */
-
- #if SEGMEM
- #else /* NOT SEGMEM */
- p = BITMAP(j, 0); /* the j-th raster line */
- #endif /* SEGMEM */
-
- c = &v8[0]; /* vertical 8-bit encodings */
- for (i = 0; i < XBIT; (++p, ++i)) /* loop over raster words */
- {
- /* PCC-20 compiled (1 << (HOST_WORD_SIZE-1)) to 0, so do it the
- hard way, arghh... */
- mask = 1;
- mask <<= (HOST_WORD_SIZE - 1); /* to select leftmost bit */
-
- #if SEGMEM
- for (k = 0; k < 8; ++k) /* compute pointers to 8 rasters */
- q[k] = BITMAP(j - k, i);
- #endif /* SEGMEM */
-
- for (k = 0; k < HOST_WORD_SIZE; (++c, ++k))/* loop over word bits */
- {
- /* examine bits in 8 adjacent rows and build 8-bit */
- /* character value */
-
- #if SEGMEM
- *c = (BYTE) makechar(q, mask);
- #else /* NOT SEGMEM */
- *c = (BYTE) makechar(&p, mask);
- #endif /* SEGMEM */
-
- mask >>= 1; /* move masking bit right 1 position */
- } /* end loop over k */
- } /* end loop over i */
- --c; /* last character encoded */
-
- (void)outline((char *) &v8[0]);
- } /* end loop over j */
-
- OUTS("\0332"); /* ESC 2 = normal paperfeeding */
- OUTC('\f'); /* eject page with FF */
-
- (void)fflush(plotfp);
- if (DISKFULL(plotfp))
- (void)fatal("prtbmap(): Output error -- disk storage probably full");
- }
- #endif /* HIRES */
-
- #include "prtpage.h"
- #include "readfont.h"
- #include "readgf.h"
- #include "readpk.h"
- #include "readpost.h"
- #include "readpxl.h"
- #include "reldfont.h"
- #include "rulepxl.h"
- #include "setchar.h"
- #include "setfntnm.h"
- #include "setrule.h"
- #include "signex.h"
- #include "skgfspec.h"
- #include "skipfont.h"
- #include "skpkspec.h"
- #include "special.h"
- #include "strchr.h"
- #include "strcm2.h"
- #include "strid2.h"
- #include "strrchr.h"
- #include "tctos.h"
- #include "usage.h"
- #include "warning.h"
-